using System.Collections.Concurrent;
using Aurora.Discovery.HttpClient.Abstractions;
using Discovery.HttpClient.Consul.Options;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.Options;
using Nacos.V2;

namespace Aurora.Discovery.HttpClient.Nacos;

/// <summary>
///  consul discovery client 
/// </summary>
public class NacosDiscoveryClient : IDiscoveryClient
{
    private readonly NacosDiscoveryOptions _options;
    private readonly Timer _timer;
    private readonly INacosNamingService _nacosNamingService;
    private readonly string _serviceIdInNacos;
    private static readonly Random _random = new Random((int)DateTime.Now.Ticks);
    private bool _useDiscovery = true;

    public ConcurrentDictionary<string, List<string>> AllServices { get; private set; } =
        new ConcurrentDictionary<string, List<string>>();

    /// <summary>
    /// 构造函数
    /// </summary>
    /// <param name="options"></param>
    public NacosDiscoveryClient(IOptions<NacosDiscoveryOptions> options, INacosNamingService nacosNamingService)
    {
        _options = options.Value;
        // 证明不启用 那么就不需要注册了
        if (_options == null)
        {
            _useDiscovery = false;
        }
        else
        {
            _nacosNamingService = nacosNamingService;
            // _timer = new Timer(Refresh);

            if (string.IsNullOrEmpty(_options.ServiceName))
            {
                _serviceIdInNacos = Guid.NewGuid().ToString();
            }
            // if (_options?.ServiceRegisterSetting != null)
            // {
            //     _serviceIdInConsul = Guid.NewGuid().ToString();
            // }
        }
    }

    /// <summary>
    /// 开启服务
    /// </summary>
    /// <exception cref="ArgumentException"></exception>
    public void Start()
    {
        if (!_useDiscovery) return;
        // var checkErrorMsg = CheckParams();
        // if (checkErrorMsg != null)
        // {
        //     throw new ArgumentException(checkErrorMsg);
        // }
        //
        // RegisterToNacos();
        // _timer.Change(0, _options.ConsulServerSetting.RefreshIntervalInMilliseconds);
    }

    /// <summary>
    /// 停止服务
    /// </summary>
    public void Stop()
    {
        if (!_useDiscovery) return;
        Dispose();
    }

    public void Use(IApplicationBuilder app)
    {
        
    }


    /// <summary>
    /// 检查参数
    /// </summary>
    /// <returns></returns>
    private string CheckParams()
    {
        if (_options.ServerAddresses?.Count <= 0)
        {
            return "Nacos 服务器地址 ServerAddresses 不能为空";
        }

        return null;
    }

    // /// <summary>
    // /// 注册服务到 nacos 中
    // /// </summary>
    // private void RegisterToNacos()
    // {
    //     if (string.IsNullOrEmpty(_serviceIdInNacos))
    //     {
    //         return;
    //     }
    //     
    //     
    //     var registerSetting = _options.ServiceRegisterSetting;
    //     var httpCheck = new AgentServiceCheck()
    //     {
    //         HTTP =
    //             $"{registerSetting.ServiceScheme}{Uri.SchemeDelimiter}{registerSetting.ServiceIP}:{registerSetting.ServicePort}/{registerSetting.HealthCheckRelativeUrl.TrimStart('/')}",
    //         Interval = TimeSpan.FromMilliseconds(registerSetting.HealthCheckIntervalInMilliseconds),
    //         Timeout = TimeSpan.FromMilliseconds(registerSetting.HealthCheckTimeOutInMilliseconds),
    //         DeregisterCriticalServiceAfter = TimeSpan.FromSeconds(10),
    //     };
    //     var registration = new AgentServiceRegistration()
    //     {
    //         ID = _serviceIdInConsul,
    //         Name = registerSetting.ServiceName,
    //         Address = registerSetting.ServiceIP,
    //         Port = registerSetting.ServicePort,
    //         Check = httpCheck,
    //         Meta = new Dictionary<string, string>() { ["scheme"] = registerSetting.ServiceScheme },
    //     };
    //     _consulClient.Agent.ServiceRegister(registration).Wait();
    // }

    // /// <summary>
    // /// 关闭服务时 释放consul的实例
    // /// </summary>
    // private void DeregisterFromConsul()
    // {
    //     if (string.IsNullOrEmpty(_serviceIdInConsul))
    //     {
    //         return;
    //     }
    //
    //     try
    //     {
    //         _consulClient.Agent.ServiceDeregister(_serviceIdInConsul).Wait();
    //     }
    //     catch
    //     {
    //     }
    // }

    // /// <summary>
    // /// 刷新缓存
    // /// </summary>
    // /// <param name="state"></param>
    // private void Refresh(object state)
    // {
    //     Dictionary<string, AgentService>.ValueCollection serversInConsul;
    //     try
    //     {
    //         serversInConsul = _consulClient.Agent.Services().Result.Response.Values;
    //     }
    //     catch // (Exception ex)
    //     {
    //         // 如果连接consul出错, 则不更新服务列表. 继续使用以前获取到的服务列表
    //         // 但是如果很长时间都不能连接consul, 服务列表里的一些实例已经不可用了, 还一直提供这样旧的列表也不合理, 所以要不要在这里实现 健康检查? 这样的话, 就得把检查地址变成不能设置的
    //         return;
    //     }
    //
    //     // 1. 更新服务列表
    //     // 2. 如果这个程序提供了服务, 还要检测 服务Id 是否在服务列表里
    //     var tempServices = new Dictionary<string, HashSet<string>>();
    //     bool needReregisterToConsul = true;
    //     foreach (var service in serversInConsul)
    //     {
    //         var serviceName = service.Service;
    //         if (!service.Meta.TryGetValue("scheme", out var serviceScheme))
    //         {
    //             serviceScheme = Uri.UriSchemeHttp;
    //         }
    //
    //         var serviceHost = $"{serviceScheme}{Uri.SchemeDelimiter}{service.Address}:{service.Port}";
    //         if (!tempServices.TryGetValue(serviceName, out var serviceHosts))
    //         {
    //             serviceHosts = new HashSet<string>();
    //             tempServices[serviceName] = serviceHosts;
    //         }
    //
    //         serviceHosts.Add(serviceHost);
    //
    //         if (needReregisterToConsul && !string.IsNullOrEmpty(_serviceIdInConsul) && _serviceIdInConsul == service.ID)
    //         {
    //             needReregisterToConsul = false;
    //         }
    //     }
    //
    //     if (needReregisterToConsul)
    //     {
    //         RegisterToConsul();
    //     }
    //
    //     var tempAllServices = new ConcurrentDictionary<string, List<string>>(StringComparer.OrdinalIgnoreCase);
    //     foreach (var item in tempServices)
    //     {
    //         tempAllServices[item.Key] = item.Value.ToList();
    //     }
    //
    //     AllServices = tempAllServices;
    // }

    public void Dispose()
    {
        if (!_useDiscovery) return;
        // DeregisterFromConsul();
        // _consulClient?.Dispose();
        //  _timer?.Dispose();
    }


    /// <summary>
    /// 获取服务
    /// </summary>
    /// <param name="host"></param>
    /// <param name="serviceHost"></param>
    /// <returns></returns>
    public async Task<string> GetService(string host)
    {
        var instance = await _nacosNamingService.SelectOneHealthyInstance(host);
        if (instance == null)
            return "";
        string serviceHost = "http://"+instance.Ip + ":" + instance.Port;

        return serviceHost;
    }
}